#ifndef BeforeExecutionTask_h
#define BeforeExecutionTask_h
#include "task.h"
#include "../abc_commons.h"

namespace task
{
    class BeforeExecutionTask : public TransformTask
    {
        using TransformTask::TransformTask;

        bool analyze(InstStructType instStruct) override
        {
            auto *block = abc::getAs<AbckitBasicBlock>(instStruct);
            if (!block)
            {
                return false;
            }
            std::cout << "BE BasicBlock分析结果: 命中!" << std::endl;
            return true;
        };

        void transform(InstStructType instStruct) override
        {
            auto apiInfo = this->param_->instApi;
            auto *block = abc::getAs<AbckitBasicBlock>(instStruct);
            std::shared_ptr<ImportDescriptor> importDescriptor = getImportDesc(apiInfo->objName);
            auto file = abckitApi->function.functionGetFile(this->func_);
            auto *ldexternalmodulevar = abckitApi->isa.iCreateLdexternalmodulevar(this->graph_, importDescriptor->i);
            abckitApi->inst.bbAddInstFront(block, ldexternalmodulevar);

            auto *myAspect = abckitApi->isa.iCreateThrowUndefinedifholewithname(this->graph_, ldexternalmodulevar, abckitApi->string.createString(file, apiInfo->objName.c_str(), strlen(apiInfo->objName.c_str())));
            abckitApi->inst.iInsertAfter(myAspect, ldexternalmodulevar);

            auto *addBefore = abckitApi->isa.iCreateLdobjbyname(this->graph_, myAspect, abckitApi->string.createString(file, apiInfo->propName.c_str(), strlen(apiInfo->propName.c_str())));
            abckitApi->inst.iInsertAfter(addBefore, myAspect);

            auto *call = abckitApi->isa.iCreateCallthis0(this->graph_, addBefore, myAspect);
            abckitApi->inst.iInsertAfter(call, addBefore);
        }
    };

} // namespace task

#endif